
import ReactDOM from 'react-dom';
import React from 'react';
import {createStore,combineReducers,applyMiddleware} from 'redux';
import {Provider,connect} from 'react-redux';
import createSagaMiddleware from 'redux-saga';
import * as effects from 'redux-saga/effects';

const NAMESPACE_SEPERATOR = '/';
export {connect};
export default function(){
  let app = {
    _models: [],
    model,
    router,
    _router: null,
    start
  }
  function model(model){
    app._models.push(model);
  }
  function router(routeConfig){
    app._router = routeConfig;
  }
  function start(root){
    let reducers = {};
    for(let model of app._models){
      reducers[model.namespace] = function(state=model.state,action){
        let actionType = action.type; // 获取动作类型 'counter/add'
        let values = actionType.split(NAMESPACE_SEPERATOR);
        if(values[0] === model.namespace){//如果命名空间名字和动作命名空间名字一样
          let reducer = model.reducers[values[1]];
          if(reducer) return reducer(state,action);
        }
        return state;
      }
    }
    let reducer = combineReducers(reducers);
    let sagaMiddleware = createSagaMiddleware();
    /**
     * takeEvery只是监听每个action，然后执行处理函数。对于何时相应action和 如何相应action，takeEvery并没有控制权。
     而take则不一样，我们可以在generator函数中决定何时相应一个action，以及一个action被触发后做什么操作。
     最大区别：take只有在执行流达到时才会响应对应的action，而takeEvery则一经注册，都会响应action。
     */
    function* rootSaga(){
       for(const model of app._models){
         for(const key in model.effects){
            yield effects.takeEvery(`${model.namespace}${NAMESPACE_SEPERATOR}${key}`,model.effects[key],effects);
         }
       }
    }

    let store = createStore(reducer,applyMiddleware(sagaMiddleware)); //创建仓库
    sagaMiddleware.run(rootSaga);
    let App = app._router;
    ReactDOM.render(
      <Provider store={store}>
        <App/>
      </Provider>,
      document.querySelector(root)
     )
  }

  return app;
}
